/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package fr.adama.repository;

import fr.adama.dto.BulletinPaieDTO;
import fr.adama.dto.CumulsDTO;
import fr.adama.dto.notModel.SearchBulletin;
import fr.adama.entite.BulletinPaie;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import org.dozer.Mapper;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.query.dsl.BooleanJunction;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 *
 * @author mini-john
 */
@Repository
public class BulletinPaieRepository extends CrudRepository {

    private static final Logger logger = LoggerFactory.getLogger(BulletinPaieRepository.class);
    @Autowired
    Mapper mapperDozer;

    public CumulsDTO getCumuls(BulletinPaieDTO bulletin) {
        BigDecimal netImposable = bulletin.getSalaireImposable();
        BigDecimal partSalarials = bulletin.getChargeSalarial();
        BigDecimal heuresTrav = bulletin.getNombreHeureTotal();
        BigDecimal brut = bulletin.getSalaireBrut();
        BigDecimal partPatronales = bulletin.getChargePatronale();
        CumulsDTO cumul = new CumulsDTO();
        String query = "from BulletinPaie where contrat.id=:contrat and annee=:annee and mois < :mois order by mois ";

        Query queryHQL = sessionFactory.getCurrentSession().createQuery(query);
        queryHQL.setParameter("contrat", bulletin.getContrat().getId());
        queryHQL.setParameter("annee", bulletin.getAnnee());
        queryHQL.setParameter("mois", bulletin.getMois());

        List<BulletinPaie> listBulletin = (List<BulletinPaie>) queryHQL.list();

        for (BulletinPaie bulletinTemp : listBulletin) {
            BulletinPaieDTO dto = mapperDozer.map(bulletinTemp, BulletinPaieDTO.class);
            netImposable = netImposable.add(dto.getSalaireImposable());
            partSalarials = partSalarials.add(dto.getChargeSalarial());
            heuresTrav = heuresTrav.add(dto.getNombreHeureTotal());
            brut = brut.add(dto.getSalaireBrut());
            partPatronales = partPatronales.add(dto.getChargePatronale());
        }
        cumul.setBrut(brut);
        cumul.setHeuresTrav(heuresTrav);
        cumul.setNetImposable(netImposable);
        cumul.setPartPatronales(partPatronales);
        cumul.setPartSalarials(partSalarials);
        return cumul;
    }

    public List<BulletinPaie> searchBulletin(SearchBulletin searchBulletin) {
        List<BulletinPaie> searchResults = new ArrayList<>();
        FullTextSession fSession = Search.getFullTextSession(sessionFactory.getCurrentSession());
        QueryBuilder queryBuilder = fSession.getSearchFactory().buildQueryBuilder().forEntity(BulletinPaie.class).get();
        boolean inQuery = false;
        BooleanJunction<BooleanJunction> queryBool = queryBuilder.bool();
        if (!searchBulletin.getNomPrenomAdherent().isEmpty()) {
            inQuery = true;
            queryBool = queryBool.should(queryBuilder.keyword().wildcard().onField("contrat.adherent.nomPrenom").ignoreAnalyzer().matching("*" + searchBulletin.getNomPrenomAdherent() + "*").createQuery());

        }
        if (!searchBulletin.getNomEmploye().isEmpty()) {
            inQuery = true;
            queryBool = queryBool.should(queryBuilder.keyword().wildcard().onField("contrat.employe.nom").ignoreAnalyzer().matching("*" + searchBulletin.getNomEmploye() + "*").createQuery());

        }
        if (!searchBulletin.getPrenomEmploye().isEmpty()) {
            inQuery = true;
            queryBool = queryBool.should(queryBuilder.keyword().wildcard().onField("contrat.employe.prenom").ignoreAnalyzer().matching("*" + searchBulletin.getPrenomEmploye() + "*").createQuery());

        }
        if (!searchBulletin.getNumero().isEmpty()) {
            inQuery = true;
            queryBool = queryBool.should(queryBuilder.keyword().wildcard().onField("numero").ignoreAnalyzer().matching("*" + searchBulletin.getNumero() + "*").createQuery());

        }
        if (!inQuery) {
            return searchResults;
        }
        org.apache.lucene.search.Query luceneQuery = queryBool.createQuery();
        org.hibernate.Query hibernateQuery = fSession.createFullTextQuery(luceneQuery, BulletinPaie.class);
        searchResults = hibernateQuery.list();

        return searchResults;
    }

    public List<BulletinPaie> getAllBulletinForPeriode(Date periode) {
        Calendar cal = GregorianCalendar.getInstance();
        cal.setTime(periode);
        int month = cal.get(Calendar.MONTH) + 1;
        int year = cal.get(Calendar.YEAR);

        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(BulletinPaie.class).createAlias("contrat", "contrat")
                .createAlias("contrat.adherent", "adherent");
        criteria.add(Restrictions.eq("annee", year)).add(Restrictions.eq("mois", month)).addOrder(Property.forName("adherent.nomPrenom").asc());
        return criteria.list();

    }

}
